package com.kantboot.functional.verification.code.service.impl;

import com.kantboot.functional.common.message.domain.dto.MessageDTO;
import com.kantboot.functional.common.message.enums.MessageStatusCodeEnum;
import com.kantboot.functional.common.message.enums.MessageTypeCodeEnum;
import com.kantboot.functional.email.service.IFunctionalEmailService;
import com.kantboot.functional.sms.service.IFunctionalSmsService;
import com.kantboot.functional.template.domain.vo.FunctionalTemplateGenerateVO;
import com.kantboot.functional.template.service.IFunctionalTemplateService;
import com.kantboot.functional.verification.code.domain.dto.SendVerificationCodeDTO;
import com.kantboot.functional.verification.code.domain.entity.FunctionalVerificationCode;
import com.kantboot.functional.verification.code.domain.entity.FunctionalVerificationCodeTemplate;
import com.kantboot.functional.verification.code.domain.enums.VerificationCodeTypeCodeEnum;
import com.kantboot.functional.verification.code.repository.FunctionalVerificationCodeRepository;
import com.kantboot.functional.verification.code.repository.FunctionalVerificationCodeTemplateRepository;
import com.kantboot.functional.verification.code.service.IFunctionalVerificationCodeService;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class FunctionalVerificationCodeServiceImpl implements IFunctionalVerificationCodeService {

    @Resource
    private FunctionalVerificationCodeRepository repository;

    @Resource
    private IFunctionalTemplateService templateService;

    @Resource
    private FunctionalVerificationCodeTemplateRepository verificationCodeTemplateRepository;

    @Resource
    private IFunctionalEmailService emailService;

    @Resource
    private IFunctionalSmsService smsService;

    @Override
    public String generateCode() {
        // 生成6位数字验证码
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            code.append((int) (Math.random() * 10));
        }
        return code.toString();
    }

    @Override
    public void send(SendVerificationCodeDTO dto) {
        // 生成的验证码
        String value = generateCode();
        // 验证码模板
        FunctionalVerificationCodeTemplate verificationCodeTemplate =
                verificationCodeTemplateRepository.findByTypeCodeAndSceneCode(dto.getTypeCode(), dto.getSceneCode());
        FunctionalTemplateGenerateVO template = templateService.getTemplate(verificationCodeTemplate.getTemplateCode(), Map.of("value", value));

        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setTo(dto.getTo());
        messageDTO.setMessageTypeCode(MessageTypeCodeEnum.VERIFICATION);
        messageDTO.setSubject(template.getTitle());
        messageDTO.setContent(template.getContent());
        messageDTO.setIsHtml(true);


        if (dto.getTypeCode().equals(VerificationCodeTypeCodeEnum.EMAIL)) {
            messageDTO.setPhoneAreaCode(null);
            dto.setPhoneAreaCode(null);
            // 发送邮箱验证码
            emailService.send(messageDTO);
        } else if (dto.getTypeCode().equals(VerificationCodeTypeCodeEnum.SMS)) {
            messageDTO.setPhoneAreaCode(dto.getPhoneAreaCode());
            // 发送短信验证码
            smsService.send(messageDTO);
        }

        FunctionalVerificationCode functionalVerificationCode = getFunctionalVerificationCode(dto, value, verificationCodeTemplate);
        repository.save(functionalVerificationCode);
    }

    /**
     * 校验
     *
     * @param dto 验证码发送数据传输对象
     * @return 是否验证通过
     */
    @NotNull
    private static FunctionalVerificationCode getFunctionalVerificationCode(SendVerificationCodeDTO dto, String value, FunctionalVerificationCodeTemplate verificationCodeTemplate) {
        FunctionalVerificationCode functionalVerificationCode = new FunctionalVerificationCode();
        functionalVerificationCode.setValue(value);
        functionalVerificationCode.setTypeCode(dto.getTypeCode());
        functionalVerificationCode.setSceneCode(dto.getSceneCode());
        functionalVerificationCode.setStatusCode(MessageStatusCodeEnum.STATUS_CODE_SUCCESS);
        functionalVerificationCode.setTo(dto.getTo());
        functionalVerificationCode.setPhoneAreaCode(dto.getPhoneAreaCode());
        // 获取过期时长
        Long expireTime = verificationCodeTemplate.getExpireTime();
        if (expireTime == null) {
            // 默认5分钟
            expireTime = 5 * 60 * 1000L;
        }
        functionalVerificationCode.setGmtExpire(new Date(System.currentTimeMillis() + expireTime));
        return functionalVerificationCode;
    }

    /**
     * 校验
     * @param dto              验证码发送数据传输对象
     * @param verificationCode 验证码
     * @return 是否验证通过
     */
    @Override
    public Boolean verify(SendVerificationCodeDTO dto, String verificationCode) {
        // 如果dto的typeCode不是SMS
        if (!dto.getTypeCode().equals(VerificationCodeTypeCodeEnum.SMS)) {
            // 设置dto的phoneAreaCode为null
            dto.setPhoneAreaCode(null);
        }

        // 获取当前时间
        long timeNow = new Date().getTime();
        List<FunctionalVerificationCode> byParam = repository.findParam(dto);
        if (byParam == null || byParam.isEmpty()) {
            return false;
        }
        for (FunctionalVerificationCode functionalVerificationCode : byParam) {
            if(functionalVerificationCode.getGmtExpire().getTime() < timeNow){
                // 删除该验证码
                repository.delete(functionalVerificationCode);
                continue;
            }
            if (functionalVerificationCode.getValue().equals(verificationCode) && functionalVerificationCode.getGmtExpire().getTime() > timeNow) {
                // 删除该验证码
                repository.delete(functionalVerificationCode);
                return true;
            }
        }
        return false;
    }


}
